package com.tyjt.common.mqtt.config;

import com.tyjt.common.mqtt.annotation.MqttListener;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.env.Environment;

import java.lang.reflect.Method;
import java.util.Map;


@Slf4j
public class MqttListenerAnnotationBeanPostProcessor implements BeanPostProcessor {
    private final String mqttGroupId;

    public MqttListenerAnnotationBeanPostProcessor(String groupId) {
        this.mqttGroupId = groupId;
    }

    @Override
    public Object postProcessBeforeInitialization(@Nonnull Object bean, @Nonnull String beanName) throws BeansException {
        return bean;
    }
    @Resource
    Environment environment;

    @Override
    public Object postProcessAfterInitialization(@Nonnull Object bean, @Nonnull String beanName) throws BeansException {

        Class<?> targetClass = AopUtils.getTargetClass(bean);

        Map<Method, MqttListener> annotatedMethods = MethodIntrospector
                .selectMethods(targetClass, (MethodIntrospector.MetadataLookup<MqttListener>) method -> AnnotatedElementUtils.findMergedAnnotation(method, MqttListener.class));

        if (!annotatedMethods.isEmpty()) {
            for (Map.Entry<Method, MqttListener> entry : annotatedMethods.entrySet()) {
                Method method = entry.getKey();
                MqttListener mqttListener = entry.getValue();
                registerHandler(mqttListener, bean, method);
            }
        }
        return bean;
    }

    private void registerHandler(MqttListener mqttListener, Object bean, Method method) {

        String topic = mqttListener.value();
        topic = environment.resolvePlaceholders(topic);
        method.setAccessible(true);
        if (topic.startsWith("$share")) {
            topic = topic.replace("$share", "$share/" + mqttGroupId);
        }
        MethodHandler methodHandler = new MethodHandler(bean, method);
        DataHandlerManager.getINSTANCE().setHandler(topic, methodHandler);
        log.info("SHARE_PREFIX：{} 处理器: {} 成功！", topic, methodHandler);
    }

}
